package com.macrounion.atv.task;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.google.common.collect.Lists;
import com.macrounion.atv.cache.DeviceCache;
import com.macrounion.atv.cache.ProtocolCache;
import com.macrounion.atv.listener.RePingGetDeviceDataListener;
import com.macrounion.atv.processor.RegProcessor;
import com.macrounion.atv.service.entity.CurrentData;
import com.macrounion.atv.service.entity.ProtocolC;
import com.macrounion.atv.service.entity.ext.DeviceExt;
import com.macrounion.atv.utils.CommandUtil;

/**
 * snmp协议数据刷新
 * @author Administrator
 *
 */
@Component
public class RePingGetTask {
	
	@Autowired
	private DeviceCache deviceCache;
	@Autowired
	private ProtocolCache protocolCache;
	@Autowired
	private RegProcessor regProcessor;
	@Autowired
	private RePingGetDeviceDataListener rePingGetDeviceDataListener;
	
	Properties props=System.getProperties();
	private String systemName =  props.getProperty("os.name").toLowerCase();
	/**
	 * ping包
	 */
	@Scheduled(cron="${timely.pingGet}")
	public void rePingData() {
		if(!regProcessor.canUse())
			return;
		List<DeviceExt> devices = deviceCache.getDevicesByStype("RePing");
		if(CollectionUtils.isEmpty(devices))
			return;
		if(!CollectionUtils.isEmpty(devices)) {
			devices.forEach(device->{
				List<ProtocolC> ps = protocolCache.getByProtocolId(device.getProtocolId());
				if(!CollectionUtils.isEmpty(ps))
					new Thread(()->{getPingData(device,ps);}).start();
			});
		}
	}
	
	private void getPingData(DeviceExt device, List<ProtocolC> ps) {
		Map<String,ProtocolC> protocolcMap = ps.parallelStream().collect(Collectors.toMap(ProtocolC::getChannelCode, o->o));			
		CommandUtil commandUtil = null;
		if(systemName.startsWith("windows"))
			commandUtil = exec("cmd.exe","/c","ping "+device.getDeviceCode());
		else
			commandUtil = exec("ping "+device.getDeviceCode()+" -c 4");
		List<CurrentData> datas = getData(commandUtil);
		rePingGetDeviceDataListener.receive(device, datas, protocolcMap);
	}

	private List<CurrentData> getData(CommandUtil commandUtil){
		List<CurrentData> datas = Lists.newArrayList();
		if(!CollectionUtils.isEmpty(commandUtil.getStdoutList())){
			int count = 0;
			int pingjun = 0;
			int doudong = 0;
			int min = 0;
			int max = 0;
			for (String std : commandUtil.getStdoutList()) {
				if(StringUtils.isEmpty(std.trim()) || std.toLowerCase().contains("ping"))
					continue;
				if(systemName.startsWith("windows")) {
					Pattern pattern = Pattern.compile("\\((.*?)\\%");
					Matcher matcher = pattern.matcher(std);
					if(matcher.find()) {
						CurrentData  c = new CurrentData();
						c.setChannelCode("002");//丢包
						c.setValues(matcher.group(1));
						datas.add(c);
						break;
					}
				}else {
					if(std.contains("%")) {
						String ds =std.split("%")[0];
						String d = "";
						try {
							d = ds.substring(ds.lastIndexOf(",")+1).trim();
						}catch (Exception e){
						}
						CurrentData  c = new CurrentData();
						c.setChannelCode("002");//丢包
						c.setValues(d);
						datas.add(c);
						break;
					}
				}
				count++;
				if(std.contains("ms")) {
					String ss =std.split("ms")[0];
					int ys = 0;
					try {
						ys = Integer.parseInt(ss.substring(ss.lastIndexOf("=")+1).trim());
					}catch (Exception e){
						ys =1;
					}
					if(ys < min || count == 1)
						min = ys;
					if(ys > max || count == 1)
						max = ys;
					pingjun = ((pingjun*(count-1))+ys)/count;
				}else {
					return outTimePing();
				}
			}
			doudong = max-min;
			CurrentData  c = new CurrentData();
			c.setChannelCode("001");//延时
			c.setValues(pingjun+"");
			datas.add(c);
			CurrentData  c1 = new CurrentData();
			c1.setChannelCode("003");//抖动
			c1.setValues(doudong+"");
			datas.add(c1);
			CurrentData  c2 = new CurrentData();
			c2.setChannelCode("004");//网络不通
			c2.setValues("0");
			datas.add(c2);
		}else if(!CollectionUtils.isEmpty(commandUtil.getErroroutList())){
			return outTimePing();
		}
		return datas;
	}
	
	private List<CurrentData> outTimePing() {
		List<CurrentData> datas = Lists.newArrayList();
		CurrentData  c = new CurrentData();
		c.setChannelCode("001");//延时
		c.setValues("-1");
		datas.add(c);
		CurrentData  c0 = new CurrentData();
		c0.setChannelCode("002");//丢包
		c0.setValues("-1");
		datas.add(c0);
		CurrentData  c1 = new CurrentData();
		c1.setChannelCode("003");//抖动
		c1.setValues("-1");
		datas.add(c1);
		CurrentData  c2 = new CurrentData();
		c2.setChannelCode("004");//网络不通
		c2.setValues("1");
		datas.add(c2);
		return datas;
	}

	private CommandUtil exec(String ...commands) {
		CommandUtil commandUtil = new CommandUtil();
		commandUtil.execCommand(commands);
		return commandUtil;
	}

}
